package sw6.visualschedule.adminpanel;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import sw6.visualschedule.R;
import sw6.visualschedule.entities.ActivityStatus;
import sw6.visualschedule.entities.ActivityStatusType;
import sw6.visualschedule.entities.DbDate;
import sw6.visualschedule.entities.ScheduleActivity;
import sw6.visualschedule.extendedViews.CustomEntry;
import sw6.visualschedule.extendedViews.SeperatorEntry;
import sw6.visualschedule.persistence.ActivityStatusRepo;
import sw6.visualschedule.persistence.DateRepo;
import sw6.visualschedule.persistence.ScheduleActivityRepo;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.DatePickerDialog.OnDateSetListener;
import android.app.ListActivity;
import android.app.TimePickerDialog;
import android.app.TimePickerDialog.OnTimeSetListener;
import android.content.DialogInterface;
import android.graphics.Color;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.DatePicker;
import android.widget.ListView;
import android.widget.TimePicker;
import android.widget.Toast;

import com.commonsware.cwac.sacklist.SackOfViewsAdapter;

public class Planning extends ListActivity {
	
	private final transient OnTimeSetListener addActivityTimeSetListener = new OnTimeSetListener() {		
		public void onTimeSet(final TimePicker view, final int hourOfDay, final int minute) {
			
			final DateRepo dateService = new DateRepo(Planning.this);
			
			final GregorianCalendar cal = new GregorianCalendar();
			cal.setTime(mDate);
			cal.set(Calendar.HOUR_OF_DAY, hourOfDay);
			cal.set(Calendar.MINUTE, minute);
			
			dateService.create(new DbDate(mAddActivity, cal.getTime()));			
			Toast.makeText(getApplicationContext(), getString(R.string.adm_ac_activity_saved), Toast.LENGTH_SHORT).show();
			populate();
		}
	};
	private final transient ScheduleActivityRepo mActivityService = new ScheduleActivityRepo(this);
	private transient SackOfViewsAdapter mAdapter;
	
	private transient ScheduleActivity mAddActivity;
	private transient Date mDate = new Date();
	
	private transient List<ScheduleActivity> mMenuItems = new ArrayList<ScheduleActivity>();
	
	private final transient OnDateSetListener showActivitiesForDateDateSetListener = new OnDateSetListener() {
		@Override
		public void onDateSet(final DatePicker view, final int year, final int monthOfYear, final int dayOfMonth) {
			final GregorianCalendar cal = new GregorianCalendar(year, monthOfYear, dayOfMonth);
			mDate = cal.getTime();
			populate();
		}
	};

	/**
	 * @see super
	 */
	@Override
	public boolean onCreateOptionsMenu(final Menu menu) {
	    final MenuInflater inflater = getMenuInflater();
	    inflater.inflate(R.menu.planning_pref, menu);
	    return true;
	}
	
	/**
	 * @see super
	 */
	@Override
	public boolean onOptionsItemSelected(final MenuItem item) {
	    // Handle item selection
	    switch (item.getItemId()) {
	    case R.id.planning_today:
	    	mDate = new Date();
	    	populate();
	        return true;
	    case R.id.planning_gotodate:	    	
	    	showActivitiesForDateDialog();
	    	populate();
	        return true;
	    case R.id.planning_previous:	    	
	    	mDate.setTime(mDate.getTime() - 86400000);	    	
	    	populate();
	        return true;
	    case R.id.planning_next:	    	
	    	mDate.setTime(mDate.getTime() + 86400000);	    	
	    	populate();
	        return true;	 
	    case R.id.planning_addactvity:	    		    		    
	    	addActivity();
	        return true;		        
	    default:
	        return super.onOptionsItemSelected(item);
	    }
	}
	
	@Override
    public void onResume() {
		super.onResume();
		populate();
	}
	
	private void addActivity() {
		//Show activity picker dialog
		mAdapter = null;
		final ArrayList<ScheduleActivity> activities = new ArrayList<ScheduleActivity>(mActivityService.getAll());
		
		final CharSequence[] items = new CharSequence[activities.size()];
		
		for (int i = 0; i < activities.size(); i++) {
			items[i] = activities.get(i).toString();
		}

		final AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle(getString(R.string.adm_planning_pick_activity));
		builder.setItems(items, new DialogInterface.OnClickListener() {
		    public void onClick(final DialogInterface dialog, final int item) {
		    	mAddActivity = activities.get(item);
		    	addActivityTimePicker();
		    }
			
		});
		
		final AlertDialog alert = builder.create();
		alert.show();
		Toast.makeText(this, getString(R.string.adm_ac_activity_saved), Toast.LENGTH_SHORT);
	}
	
	private void addActivityTimePicker() {
		final GregorianCalendar cal = new GregorianCalendar();
		new TimePickerDialog(this, addActivityTimeSetListener, cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), true).show();		
	}
	
	private void populate() {
		mMenuItems = new ArrayList<ScheduleActivity>( mActivityService.getActivities(mDate));
		
		final ArrayList<View> views = new ArrayList<View>();
		
		views.add(new SeperatorEntry(this, DateFormat.getDateInstance(java.text.DateFormat.MEDIUM).format(mDate).toString()));		
		
		final GregorianCalendar cal = new GregorianCalendar();
		for (ScheduleActivity scheduleActivity : mMenuItems) {
			final CustomEntry entry = new CustomEntry(this);
			entry.setId(scheduleActivity.getId());
			entry.getTitle().setText(scheduleActivity.getTitle());
			
			cal.setTime(scheduleActivity.getInstanceDate());
			
			final int hour = cal.get(Calendar.HOUR_OF_DAY);
			final int min = cal.get(Calendar.MINUTE);
			String hourTxt;
			String minuteTxt;
			
			if (hour < 10) {
				hourTxt = "0" + hour;
			} else {
				hourTxt = String.valueOf(hour);
			}
			
			if (min < 10) {
				minuteTxt = "0" + min;
			} else {
				minuteTxt = String.valueOf(min);
			}
			
			final String time = hourTxt + ":" + minuteTxt;
			
			if (scheduleActivity.getInstanceStatus() == null) {
				entry.getSummary().setText(getString(R.string.adm_planning_unfinished_scheduled) + " " + time);
			} else {
				switch ( scheduleActivity.getInstanceStatus() ) {
				case NEW:
					entry.getSummary().setText(getString(R.string.adm_planning_unfinished_scheduled) + " " + time);
					break;
				case FINISHED:
					entry.getSummary().setText(getString(R.string.adm_planning_finished_scheduled) + " " + time);
					break;	
				case SKIPPED:
					entry.getSummary().setText(getString(R.string.adm_planning_skipped_scheduled) + " " + time);
					break;
				case DISABLED:
					entry.getSummary().setText(getString(R.string.adm_planning_activity_disabled));
					entry.getTitle().setTextColor(Color.DKGRAY);
					entry.getSummary().setTextColor(Color.DKGRAY);
					break;
				default:
					break;
				}			
			}
			views.add(entry);
		}
		
		mAdapter = new SackOfViewsAdapter(views);
		setListAdapter(mAdapter);
	}

	private void showActivitiesForDateDialog() {
		final GregorianCalendar cal = new GregorianCalendar();
		cal.setTime(mDate);
		new DatePickerDialog(this, showActivitiesForDateDateSetListener, cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH)).show();
	}	
	
	@Override
	protected void onListItemClick(final ListView list, final View view, final int position, final long itemId) {
		super.onListItemClick(list, view, position, itemId);

		//if seperator is clicked.
		if(position == 0)
		{
			return;
		}
		
		final ScheduleActivity selectedActivity = mMenuItems.get(position-1);
		final ActivityStatus status = new ActivityStatus(selectedActivity, selectedActivity.getInstanceDate());
		final ActivityStatusType type = selectedActivity.getInstanceStatus();
		
		if (type != ActivityStatusType.FINISHED) {
			if (type == ActivityStatusType.DISABLED) {
				/*TODO: Notice that when enabling an activity, the status is set to new. Should we
				 * create the activityStatusType.DISABLED as a seperate property? 
				 */
				Toast.makeText(this, getString(R.string.adm_planning_enabled) + " " + selectedActivity.getTitle() , Toast.LENGTH_SHORT).show();
	
	            status.setStatus(null);
			} else {
				Toast.makeText(this, getString(R.string.adm_planning_disabled) + " " + selectedActivity.getTitle() , Toast.LENGTH_SHORT).show();
	            status.setStatus(ActivityStatusType.DISABLED);
			}
			
			new ActivityStatusRepo(Planning.this).insertOrUpdate(status);
			
			populate();
		} else {
			Toast.makeText(this, getString(R.string.adm_planning_unable), Toast.LENGTH_SHORT).show();
		}
	}	
}